#region File Description
//-----------------------------------------------------------------------------
// GameplayScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Threading;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#endregion

namespace PrehistoricGame
{
    /// <summary>
    /// This screen implements the actual game logic. It is just a
    /// placeholder to get the idea across: you'll probably want to
    /// put some more interesting gameplay in here!
    /// </summary>
    class GameplayScreen : GameScreen
    {
        #region Fields

        ContentManager content;
        SpriteFont gameFont;

        Vector2 cameraPosition = new Vector2(400, 380); //The point at which the camera is focused, to be used by the scrolling backgrounds
        Vector2 cameraTarget = new Vector2(400, 380);   //The point at which the camera should shift focus to in the coming frames
        float cameraShiftSpeed = 5f;                  //The speed at which the camera is able to shift focus

        Vector2 playerDrawPosition = new Vector2(100, 380); //The point at which the player character is drawn
        Vector2 playerDrawTarget = new Vector2(100, 350);   //The point at which the player character should move on screen. This is used when the player's orientation changes.

        Vector2 playerPosition = new Vector2(0, 380);   //Starting position for the player. To be removed later

        Player player;// = new Player();                   //No comment.
        //Texture2D playerTex;                            //To be replaced by animation system/sheet

        BackgroundManager bgm = new BackgroundManager(); //Everything behind the gameplay layer
        BackgroundManager fgm = new BackgroundManager(); //Everything in front of the gameplay layer

        Random random = new Random();                   //90dm209mntn290fn38itmvb3bc98h3trnby0

        float pauseAlpha;

        #endregion

        #region Initialization


        /// <summary>
        /// Constructor.
        /// </summary>
        public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
        }


        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            gameFont = content.Load<SpriteFont>("gamefont");
            fgm.addNonWrappedBackground(content.Load<Texture2D>("testBG"), 1.02f, new Vector2(1000,400));
            bgm.addWrappedBackground(content.Load<Texture2D>("bg4000"), 0.6f, new Vector2(0,220));

            //playerTex = content.Load<Texture2D>("neandersheet");
            //player.Position = playerPosition;
            player = new Player(playerPosition, 
                //new Animation(content.Load<Texture2D>("neanderidle"), 1f, true), 
                //new Animation(content.Load<Texture2D>("neanderrun"), 0.1f, true),
                new Animation(content.Load<Texture2D>("policeidle"), 0.6f, true),
                new Animation(content.Load<Texture2D>("policemove"), 0.4f, true),
                new Animation(content.Load<Texture2D>("neanderjump"), 0.3f, false),
                new Animation(content.Load<Texture2D>("neanderhits"), 0.4f, false));

            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            ScreenManager.Game.ResetElapsedTime();
        }


        /// <summary>
        /// Unload graphics content used by the game.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }


        #endregion

        #region Update and Draw


        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);
            float secondselapsed = (float)gameTime.ElapsedGameTime.Milliseconds / 1000f;

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);

            if (IsActive)
            {
                player.Update(gameTime, Keyboard.GetState());
                
                if (player.CurrentOrientation == Player.PlayerOrientation.Right)
                {
                    cameraTarget = player.Position + new Vector2(300, 0);
                    playerDrawTarget = new Vector2(100, 550);
                }
                else
                {
                    cameraTarget = player.Position + new Vector2(-300, 0);
                    playerDrawTarget = new Vector2(1400, 550);
                }

                Vector2.Lerp(ref cameraPosition, ref cameraTarget, cameraShiftSpeed * secondselapsed, out cameraPosition);
                Vector2.Lerp(ref playerDrawPosition, ref playerDrawTarget, cameraShiftSpeed * secondselapsed, out playerDrawPosition);
            }
        }


        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            // Look up inputs for the active player profile.
            int playerIndex = (int)ControllingPlayer.Value;

            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
            GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];

            // The game pauses either if the user presses the pause button, or if
            // they unplug the active gamepad. This requires us to keep track of
            // whether a gamepad was ever plugged in, because we don't want to pause
            // on PC if they are playing with a keyboard and have no gamepad at all!
            bool gamePadDisconnected = !gamePadState.IsConnected &&
                                       input.GamePadWasConnected[playerIndex];

            if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
            {
                ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            }
        }


        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
                                               Color.CornflowerBlue, 0, 0);

            // Retrieve spritebatch for drawing
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            spriteBatch.Begin();

            //Draw background textures
            bgm.Draw(gameTime, spriteBatch, cameraPosition, ScreenManager.GraphicsDevice.Viewport);

            //Draw player sprite -STUB-
            //spriteBatch.Draw(playerTex, new Rectangle((int)playerDrawPosition.X, (int)playerDrawPosition.Y, 240, 240), new Rectangle(0, 0, 540, 540), Color.White, 0f, Vector2.Zero, 
            //    (player.CurrentOrientation == Player.PlayerOrientation.Right)? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0f);
            player.Draw(gameTime, spriteBatch, playerDrawPosition);

            //DEBUG INFO ON PLAYER STATE AND ORIENTATION
            spriteBatch.DrawString(gameFont, player.CurrentState.ToString() + " " + player.CurrentOrientation.ToString(), playerDrawPosition, Color.Red, 0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0f);

            //Draw Foreground textures
            fgm.Draw(gameTime, spriteBatch, cameraPosition, ScreenManager.GraphicsDevice.Viewport);

            spriteBatch.End();

            // If the game is transitioning on or off, fade it out to black.
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }


        #endregion
    }
}
